package com.yiren.dbaa.module.exam.api.impl;

import android.app.Activity;
import android.os.Handler;
import android.text.TextUtils;
import android.util.Log;

import com.blankj.utilcode.util.LogUtils;
import com.blankj.utilcode.util.TimeUtils;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.yiren.backstage.App;
import com.yiren.backstage.config.api.LoadConfigApi;
import com.yiren.backstage.config.bean.device.StationParamConfigBean;
import com.yiren.backstage.currency.bean.CarStateBean;
import com.yiren.backstage.currency.bean.GpsInfoBean;
import com.yiren.backstage.currency.entity.GradeStandardEntity;
import com.yiren.backstage.currency.entity.ProjectEntity;
import com.yiren.backstage.currency.entity.record.CarInfoRecordEntity;
import com.yiren.backstage.currency.entity.record.CarRecordPointEntity;
import com.yiren.backstage.currency.entity.record.ProjectGradeEntity;
import com.yiren.backstage.currency.entity.record.ProjectInfoEntity;
import com.yiren.backstage.currency.enums.TaskStateEnum;
import com.yiren.backstage.currency.utils.GpsUtil;
import com.yiren.dbaa.constant.AddressConstant;
import com.yiren.dbaa.module.exam.api.IExamRecordApi;
import com.yiren.dbaa.module.exam.bean.DriveDataBean;
import com.yiren.dbaa.module.exam.bean.DriveRecordBean;
import com.yiren.dbaa.module.exam.bean.record.CarInfoRecordBean;
import com.yiren.dbaa.module.exam.bean.record.CarRecordPointBean;
import com.yiren.dbaa.module.exam.bean.record.ExecutingPointBean;
import com.yiren.dbaa.module.exam.bean.record.ProjectGradeBean;
import com.yiren.dbaa.module.exam.bean.record.ProjectInfoBean;
import com.yiren.dbaa.module.exam.view.id.ExamMapId;
import com.yiren.dbaa.module.practice_set.map.contract.CollectContract;
import com.yiren.dbaa.module.practice_set.map.model.CollectModel;
import com.yiren.dbaa.net.OkHttpUtils;
import com.yiren.dbaa.net.bean.BaseResponseBean;
import com.yiren.dbaa.net.interf.StringCallback;
import com.yiren.dbaa.util.JacksonUtils;

import org.apache.commons.lang.StringUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by WANGRONGXIANG
 * on 2022/5/16
 * Describe
 */
public class ExamRecordApiImpl implements IExamRecordApi {

    public final static String TAG = "ExamRecordApiImpl";

    private Activity mActivity;
    private String voiceTxt;
    private StationParamConfigBean stationParamConfig;
    private CollectContract.Model collectModel;
    private boolean isBaseCalibration;   //点位是否全部采用标定后的基站采集

    public ExamRecordApiImpl(Activity mActivity) {
        this.mActivity = mActivity;
        stationParamConfig = LoadConfigApi.loadStationParamConfig(mActivity);
        collectModel = new CollectModel(mActivity);
        isBaseCalibration = collectModel.loadPointCalibrationStatus(stationParamConfig.isBaseCalibration());
    }

    @Override
    public void setVoiceTxt(String voiceTxt) {
        this.voiceTxt = voiceTxt;
    }

    @Override
    public void uploadCurProjectPoint(ExecutingPointBean executingPointBean, boolean isGjdShow, String lineId, String lineSessionId, String stuId) {
        CarInfoRecordBean carInfoRecord = new CarInfoRecordBean();
        ProjectInfoBean projectInfo = new ProjectInfoBean();
        List<CarRecordPointBean> beans = executingPointBean.getBeans();
        if (isGjdShow) projectInfo.setLineId(lineId);
        projectInfo.setName(executingPointBean.getProject().getName());
        //是否是全程评判
        projectInfo.setTime(System.currentTimeMillis() - executingPointBean.getId());
        List<ProjectGradeBean> gradeBeans = new ArrayList<>();
        for (CarRecordPointBean bean : beans) {
            String cause  = bean.getCause();
            if (!TextUtils.isEmpty(cause)) {
                ProjectGradeBean gradeBean = new ProjectGradeBean(cause, bean.getScore(), bean.getTime());
                gradeBeans.add(gradeBean);
            }
        }
        projectInfo.setProjectGrade(gradeBeans);
        carInfoRecord.setIndex(executingPointBean.getId());
        carInfoRecord.setTime(TimeUtils.getNowString());
        carInfoRecord.setUse_line_session_id(lineSessionId);
        carInfoRecord.setStu_id(stuId);
        carInfoRecord.setCalibration(isBaseCalibration && stationParamConfig.isBaseCalibration() ? 1 : 0);
        carInfoRecord.setBasePoint(stationParamConfig.getBaseStationLocation());
        carInfoRecord.setProjectInfo(projectInfo);
        carInfoRecord.setCarRecordPoint(beans);
        //项目结束时,会把数据全部存储在数据库,然后重新开始存储
        executingPointBean.setUpload(true);
        uploadCarRecord(carInfoRecord);
    }

    @Override
    public void addCarGradeRecord(String key, GradeStandardEntity gradeStandardEntity, List<ExecutingPointBean> executingPoints) {
        String projectId = gradeStandardEntity.getProjectId();
        if (projectId.equals("30000") || projectId.equals("30100") || projectId.equals("30200")) {
            //将全程评判、综合评判统一归纳为全程评判里面
            projectId = "30000";
        }
        for (int i = executingPoints.size() - 1; i >= 0; i--) {
            if (projectId == executingPoints.get(i).getProject().getId()) {
                CarRecordPointBean carCarRecordPointBean = new CarRecordPointBean();
                carCarRecordPointBean.setName(gradeStandardEntity.getProjectEntity().getName());
                carCarRecordPointBean.setGradeId(key);
                carCarRecordPointBean.setScore(gradeStandardEntity.getGrade());
                carCarRecordPointBean.setCause(gradeStandardEntity.getStandardContent());
                carCarRecordPointBean.setTime(System.currentTimeMillis());
                executingPoints.get(i).getBeans().add(carCarRecordPointBean);
                break;
            }
        }
    }

    @Override
    public void deleteGradeRecord(String projectId, String key, List<ExecutingPointBean> executingPoints) {
        for (ExecutingPointBean executingPoint : executingPoints) {
            if (executingPoint.getProject().getId().equals("projectId")) {
                List<CarRecordPointBean> beans = executingPoint.getBeans();
                for (int i = 0; i < beans.size(); i++) {
                    String gradeId = beans.get(i).getGradeId();
                    if (StringUtils.isNotEmpty(gradeId) && gradeId.equals(key)) {
                        beans.remove(i);
                        executingPoint.setModify(true);
                    }
                }
            }
        }
    }

    @Override
    public CarRecordPointBean createRecordPointBean(CarStateBean carState, GpsInfoBean gps, ExamMapId idMap) {
        CarRecordPointBean record = new CarRecordPointBean();
        if (idMap.isGjdShow()) {
            if (isBaseCalibration && stationParamConfig.isBaseCalibration()) {
                String locations[] = stationParamConfig.getBaseStationLocation().split(",");
                record.setX(GpsUtil.getDistanceX(Double.parseDouble(locations[0]), Double.parseDouble(locations[1]), gps.getLongitude()));
                record.setY(GpsUtil.getDistanceY(Double.parseDouble(locations[1]), gps.getLatitude()));
            } else {
                record.setX(gps.getDistanceX());
                record.setY(gps.getDistanceY());
            }
            record.setX(gps.getDistanceX());
            record.setY(gps.getDistanceY());
            record.setCa(gps.getAzimuth());
            record.setDl(String.valueOf(carState.getLeftFrontDistance()));
            record.setDr(String.valueOf(carState.getRightFrontDistance()));
        } else {
            record.setL(gps.getLongitude());
            record.setW(gps.getLatitude());
            record.setCa(gps.getBearing());
            record.setFy(String.valueOf(gps.getAnglePitch()));
        }
        if (StringUtils.isNotEmpty(voiceTxt)) {
            record.setVoice(voiceTxt);
            voiceTxt = "";
        }
        record.setGear(carState.getGear().getName());
        if (carState.getSpeed() != 0) record.setSpeed((int) carState.getSpeed());
        record.setTime(System.currentTimeMillis());
        record.setDg(idMap.getDg());
        return record;
    }

    @Override
    public void addPracticeData(List<ExecutingPointBean> executingPointBeans, CarStateBean carState, GpsInfoBean gps, ExamMapId idMap) {
        if (executingPointBeans.size() == 0) return;
        for (ExecutingPointBean executingPointBean : executingPointBeans) {
            if (executingPointBean.getProject().getName().contains("全程") || executingPointBean.getProject().getName().contains("综合"))
                continue;
            if (!executingPointBean.isUpload()) {
                List<CarRecordPointBean> beans = executingPointBean.getBeans();
                CarRecordPointBean carRecordPointBean = createRecordPointBean(carState, gps, idMap);
                beans.add(carRecordPointBean);
            }
        }
    }

    @Override
    public void create2UploadCarRecord(List<ExecutingPointBean> executingPoints, ProjectEntity projectEntity, TaskStateEnum taskState, ExamMapId idMap, String lineId, String lineSessionId, String stuId) {
        if (taskState == TaskStateEnum.IN_PROCESS) {
            List<CarRecordPointBean> carCarRecordPointBean = new ArrayList<>();
            CarRecordPointBean carRecordPointBean = createRecordPointBean(CarStateBean.getInstance(), GpsInfoBean.getInstance(), idMap);
            carCarRecordPointBean.add(carRecordPointBean);
            ExecutingPointBean curProjectPoint = new ExecutingPointBean(projectEntity, carCarRecordPointBean);
            executingPoints.add(curProjectPoint);
        } else if (taskState == TaskStateEnum.FINISH) {
            for (ExecutingPointBean executingPoint : executingPoints) {
                if (projectEntity.getId() == executingPoint.getProject().getId() && !executingPoint.isUpload()) {
                    executingPoint.setUpload(true);
                    //项目执行完成,延迟1s上传数据
                    new Handler().postDelayed(() -> uploadCurProjectPoint(executingPoint, idMap.isGjdShow(), lineId, lineSessionId, stuId), 1000);
                }
            }
        }
    }

    @Override
    public void endExamUploadCarRecord(List<ExecutingPointBean> executingPoints, boolean isGjdShow, String lineId, String lineSessionId, String stuId) {
        for (ExecutingPointBean executingPoint : executingPoints) {
            if (!executingPoint.isUpload() || executingPoint.isModify()) {
                executingPoint.setUpload(true);
                executingPoint.setModify(false);
                uploadCurProjectPoint(executingPoint, isGjdShow, lineId, lineSessionId, stuId);
            }
        }
    }

    @Override
    public void uploadCarRecord(CarInfoRecordBean carInfoRecordBean) {
        new Thread(() -> {
            //这里解析耗时间，放在线程里面执行
            String json = JacksonUtils.toJsonString(carInfoRecordBean);
            OkHttpUtils.getInstance().postJsonString(mActivity, AddressConstant.uploadRealtimeTraject(), json, new StringCallback() {
                @Override
                public void getString(String result) {
                    saveCarRecordDb(carInfoRecordBean, true);
                }

                @Override
                public void getFail() {
                    saveCarRecordDb(carInfoRecordBean, false);
                }
            });
        }).start();
    }

    /**
     * 保存练车记录到数据库
     *
     * @param carInfoRecordBean
     * @param isUpload          true:上传成功  false：需要重新上传
     */
    private void saveCarRecordDb(CarInfoRecordBean carInfoRecordBean, boolean isUpload) {
        new Thread(() -> {
            //车辆信息记录存储
            CarInfoRecordEntity carInfoRecordEntity = new CarInfoRecordEntity();
            carInfoRecordEntity.setUse_line_session_id(carInfoRecordBean.getUse_line_session_id());
            carInfoRecordEntity.setStu_id(carInfoRecordBean.getStu_id());
            carInfoRecordEntity.setCalibration(carInfoRecordBean.getCalibration());
            carInfoRecordEntity.setBasePoint(carInfoRecordBean.getBasePoint());
            carInfoRecordEntity.setIndex(carInfoRecordBean.getIndex());
            carInfoRecordEntity.setTime(carInfoRecordBean.getTime());
            carInfoRecordEntity.setIsUpload(isUpload);
            App.getInstance().getCacheSession().insert(carInfoRecordEntity);

            //点位数据存储
            List<CarRecordPointBean> carRecordPoints = carInfoRecordBean.getCarRecordPoint();
            if (null != carRecordPoints && carRecordPoints.size() > 0) {
                for (CarRecordPointBean carRecordPoint : carRecordPoints) {
                    CarRecordPointEntity carRecordPointEntity = new CarRecordPointEntity();
                    carRecordPointEntity.setRecordId(carInfoRecordEntity.getId());
                    carRecordPointEntity.setX(carRecordPoint.getX());
                    carRecordPointEntity.setY(carRecordPoint.getY());
                    carRecordPointEntity.setL(carRecordPoint.getL());
                    carRecordPointEntity.setW(carRecordPoint.getW());
                    carRecordPointEntity.setCa(carRecordPoint.getCa());
                    carRecordPointEntity.setDr(carRecordPoint.getDr());
                    carRecordPointEntity.setDl(carRecordPoint.getDl());
                    carRecordPointEntity.setFy(carRecordPoint.getFy());
                    carRecordPointEntity.setTime(carRecordPoint.getTime());
                    carRecordPointEntity.setDg(carRecordPoint.getDg());
                    carRecordPointEntity.setGradeId(carRecordPoint.getGradeId());
                    carRecordPointEntity.setCause(carRecordPoint.getCause());
                    carRecordPointEntity.setScore(carRecordPoint.getScore());
                    carRecordPointEntity.setName(carRecordPoint.getName());
                    carRecordPointEntity.setVoice(carRecordPoint.getVoice());
                    carRecordPointEntity.setGear(carRecordPoint.getGear());
                    carRecordPointEntity.setSpeed(carRecordPoint.getSpeed());
                    App.getInstance().getCacheSession().insert(carRecordPointEntity);
                }
            }

            //项目信息存储
            ProjectInfoBean projectInfo = carInfoRecordBean.getProjectInfo();
            ProjectInfoEntity projectInfoEntity = new ProjectInfoEntity();
            projectInfoEntity.setRecordId(carInfoRecordEntity.getId());
            projectInfoEntity.setLineId(projectInfo.getLineId());
            projectInfoEntity.setName(projectInfo.getName());
            projectInfoEntity.setTime(projectInfo.getTime());
            App.getInstance().getCacheSession().insert(projectInfoEntity);

            //项目评判存储
            List<ProjectGradeBean> projectGrades = projectInfo.getProjectGrade();
            if (null != projectGrades && projectGrades.size() > 0) {
                for (ProjectGradeBean projectGradeBean : projectGrades) {
                    ProjectGradeEntity projectGradeEntity = new ProjectGradeEntity();
                    projectGradeEntity.setProjectId(projectInfoEntity.getId());
                    projectGradeEntity.setCause(projectGradeBean.getCause());
                    projectGradeEntity.setGrade(projectGradeBean.getGrade());
                    projectGradeEntity.setTime(projectGradeBean.getTime());
                    App.getInstance().getCacheSession().insert(projectGradeEntity);
                }
            }
        }).start();
    }

    @Override
    public void uploadStartExamData(DriveRecordBean startRecord) {
        OkHttpUtils.getInstance().postJsonString(mActivity, AddressConstant.getDrivingStartUrl(null != LoadConfigApi.loadUserParamConfig(mActivity).getUserInfo()), new Gson().toJson(startRecord), new StringCallback() {
            @Override
            public void getString(String result) {
                Log.i(TAG, "练车记录发送成功：" + result);
            }

            @Override
            public void getFail() {
                Log.e(TAG, "练车记录发送失败");
            }
        });
    }

    @Override
    public void uploadEndExamData(DriveDataBean driveData) {
        List<DriveDataBean> list = new ArrayList<>();
        list.add(driveData);
        if (null != list && list.size() > 0) {
            OkHttpUtils.getInstance().postJsonString(mActivity, AddressConstant.getReissueDrivingUrl(), new Gson().toJson(list), new StringCallback() {
                @Override
                public void getString(String result) {
                    BaseResponseBean<Boolean> baseResponseBean = new Gson().fromJson(result, new TypeToken<BaseResponseBean<Boolean>>() {
                    }.getType());
                    if (baseResponseBean.getError() == null && baseResponseBean.getResult()) {
                        LogUtils.d("补发成功: ");
                    } else {
                        LogUtils.d("补发失败: " + result);
                    }
                }

                @Override
                public void getFail() {
                    LogUtils.d("补发失败: ");
                }
            });
        }
    }
}
